Skip to content

Allow type checkers to infer more precise types for tuples#2194

Open
davidhalter wants to merge 4 commits intopython:mainfrom
davidhalter:zuban-update
Open

Allow type checkers to infer more precise types for tuples#2194
davidhalter wants to merge 4 commits intopython:mainfrom
davidhalter:zuban-update

Conversation

@davidhalter
Copy link
Contributor

This is consisent with the latest changes where f(1) could either be an int or a Literal[1]

    def f[T](x: T) -> T: ...
    assert_type(f(1), int)
    # or
    assert_type(f(1), Literal[1])

The same is possible with tuples:

    def f[*Ts](*x: *Ts) -> tuple[*Ts]: ...
    assert_type(f(1), tuple[int])
    # or
    assert_type(f(1), tuple[Literal[1]])

Mypy fails the test generics_typevartuple_callable.py now, because it doesn't error on any of the assert_type below:

def func3(*args: * tuple[int, *Ts, T]) -> tuple[T, *Ts]:
    raise NotImplementedError

assert_type(func3(1, "", 3j, 3.4), tuple[float, str, complex])  # E[fun3]
assert_type(func3(1, "", 3j, 3.4), tuple[float, Literal[''], complex])  # E[fun3]

This is also how Zuban used to work, but I think it's better to be precise here and it should probably fail one of the two (like Eric suggested in #2178 (comment)).

Ran the automated tests again. A few changes:

  • Zuban's passes a test again (due to assert_type changes)
  • Picked up a pyrefly upgrade that fixes a test

This is consisent with the latest changes where f(1) could either be an
int or a Literal[1]

    def f[T](x: T) -> T: ...
    assert_type(f(1), int)
    # or
    assert_type(f(1), Literal[1])

The same is possible with tuples:

    def f[*Ts](*x: *Ts) -> tuple[*Ts]: ...
    assert_type(f(1), tuple[int])
    # or
    assert_type(f(1), tuple[Literal[1]])


assert_type(args_to_tuple(1, "a"), tuple[int, str])
assert_type(args_to_tuple(1, "a"), tuple[int, str]) # E[args_to_tuple]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid the two options, could we put this in a function that takes args of type int and str? Then tuple[int, str] would be unambiguously right.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Jelle, that's a really good idea, it also feels more readable this way for people that are not used to the special # E[...] comments.

I pushed this. This makes Mypy pass generics_typevartuple_callable.py again and doesn't really change anything other than Zuban passing the tests with its latest release.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I weakly prefer the version prior to c1ffe96. The new version could pass even if the type checker completely fails to solve the TypeVarTuple and just falls back to *tuple[Any, ...] for its inference of *Ts. The version with the # E[] tagged errors was precise

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't think about that. That's obviously a problem. I'm happy to revert...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant something like this:

def func(x: int, y: str):
    assert_type(args_to_tuple(x, y), tuple[int, str])

I agree the current version is worse.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JelleZijlstra's version there works for me, yes!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexWaygood @JelleZijlstra Thank you for the good feedback. Kind of stupid of me to not think of this in the first place. I think the change is now completely uncontroversial.

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes sense to me, thanks!

@AlexWaygood AlexWaygood added the topic: conformance tests Issues with the conformance test suite label Feb 26, 2026
@AlexWaygood
Copy link
Member

I don't think this is controversial, but I'll wait for sign-off from another typing-council member before landing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: conformance tests Issues with the conformance test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants